/**
 * 
 */
package jvs.vfs.opt.media;

import java.net.URI;
import java.util.ArrayList;

import jvs.vfs.IFile;
import jvs.vfs.opt.ItemInfo;
import jvs.vfs.opt.ItemListFileImpl;
import android.content.Context;
import android.database.Cursor;
import android.provider.MediaStore;
import android.util.Log;

/**
 * @author qiangli
 * 
 */
public class MusicFileImpl extends ItemListFileImpl {
	private static class MusicInfo extends ItemInfo {
		public String type;
	}

	private static final String[] LIST = { "/album", "/artist", "/playlist",
			"/genre", "/title", };

	private static ItemInfo[][] lists = new ItemInfo[LIST.length][];

	private static final int LIST_ALBUM = 0;
	private static final int LIST_ARTIST = 1;
	private static final int LIST_PLAYLIST = 2;
	private static final int LIST_GENRE = 3;
	private static final int LIST_TITLE = 4;

	private static final String LOG_TAG = "MusicFileImpl";

	private static void loadAlbum(Context ctx, ArrayList<ItemInfo> list) {
		final String sel = MediaStore.Audio.Albums.ALBUM + " != ''";
		final String[] proj = new String[] { MediaStore.Audio.Albums._ID,
				MediaStore.Audio.Albums.ARTIST, MediaStore.Audio.Albums.ALBUM,
				MediaStore.Audio.Albums.ALBUM_ART,
				MediaStore.Audio.Albums.FIRST_YEAR,
				MediaStore.Audio.Albums.NUMBER_OF_SONGS };
		Cursor c = MediaUtils.query(ctx,
				MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, proj, sel, null,
				MediaStore.Audio.Albums.DEFAULT_SORT_ORDER);

		if (DEBUG) {
			Log.d(LOG_TAG, "loadAlbum: " + c);
		}
		if (c == null) {
			return;
		}
		list.clear();
		try {
			if (!c.moveToFirst()) {
				return;
			}
			long key = System.currentTimeMillis();
			//
			int idIdx = c.getColumnIndexOrThrow(MediaStore.Audio.Albums._ID);
			int albumIdx = c
					.getColumnIndexOrThrow(MediaStore.Audio.Albums.ALBUM);
			int artistIdx = c
					.getColumnIndexOrThrow(MediaStore.Audio.Albums.ARTIST);
			int artIdx = c
					.getColumnIndexOrThrow(MediaStore.Audio.Albums.ALBUM_ART);
			// int year1Idx = c
			// .getColumnIndexOrThrow(MediaStore.Audio.Albums.FIRST_YEAR);
			// int songsIdx = c
			// .getColumnIndexOrThrow(MediaStore.Audio.Albums.NUMBER_OF_SONGS);
			do {
				MusicInfo i = new MusicInfo();
				int id = c.getInt(idIdx);
				i.id = id + "";
				String s1 = c.getString(albumIdx);
				boolean unknown = (s1 == null || s1
						.equals(MediaFile.UNKNOWN_STRING));
				if (unknown) {
					s1 = "Unknown Album";
				}
				String s2 = c.getString(artistIdx);
				if (s2 == null || s2.equals(MediaFile.UNKNOWN_STRING)) {
					s2 = "Unknown Artist";
				}
				// We don't actually need the path to the thumbnail file,
				// we just use it to see if there is album art or not
				String art = c.getString(artIdx);
				if (unknown || art == null || art.length() == 0) {
					i.icon = null;
				} else {
					i.icon = ArtworkCache.getCachedArtworkIcon(ctx, id);
				}
				i.title = s1 + ", " + s2;
				// i.year = c.getLong(year1Idx);
				// i.songs = c.getInt(songsIdx);
				//
				key++;
				i.sortkey = key + "";
				list.add(i);
			} while (c.moveToNext());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			c.close();
		}
	}

	private static void loadArtist(Context ctx, ArrayList<ItemInfo> list) {
		final String sel = MediaStore.Audio.Artists.ARTIST + " != ''";
		final String[] proj = new String[] { MediaStore.Audio.Artists._ID,
				MediaStore.Audio.Artists.ARTIST,
				MediaStore.Audio.Artists.NUMBER_OF_ALBUMS,
				MediaStore.Audio.Artists.NUMBER_OF_TRACKS };
		Cursor c = MediaUtils.query(ctx,
				MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI, proj, sel, null,
				MediaStore.Audio.Artists.ARTIST_KEY);

		if (DEBUG) {
			Log.d(LOG_TAG, "loadArtist: " + c);
		}
		if (c == null) {
			return;
		}
		list.clear();
		try {
			if (!c.moveToFirst()) {
				return;
			}
			long key = System.currentTimeMillis();

			int idIdx = c.getColumnIndexOrThrow(MediaStore.Audio.Artists._ID);
			int artistIdx = c
					.getColumnIndexOrThrow(MediaStore.Audio.Artists.ARTIST);
			// int albumIdx = c
			// .getColumnIndexOrThrow(MediaStore.Audio.Artists.NUMBER_OF_ALBUMS);
			// int songIdx = c
			// .getColumnIndexOrThrow(MediaStore.Audio.Artists.NUMBER_OF_TRACKS);

			do {
				MusicInfo i = new MusicInfo();
				int id = c.getInt(idIdx);
				i.id = id + "";
				String s1 = c.getString(artistIdx);
				if (s1 == null || s1.equals(MediaFile.UNKNOWN_STRING)) {
					s1 = "Unknown Artist";
				}
				i.title = s1;
				//
				key++;
				i.sortkey = key + "";
				list.add(i);
			} while (c.moveToNext());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			c.close();
		}
	}

	private static void loadAudio(Context ctx, ArrayList<ItemInfo> list) {
		String[] proj = { MediaStore.Audio.Media._ID,
				MediaStore.Audio.Media.DISPLAY_NAME,
				MediaStore.Audio.Media.DATA };
		Cursor c = MediaUtils.query(ctx,
				MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, proj, null, null,
				MediaStore.Audio.Media.DISPLAY_NAME);
		list.clear();
		if (c == null) {
			return;
		}
		if (DEBUG) {
			Log.d(LOG_TAG, "loadAudio: " + c + " count: " + c.getCount());
		}
		try {
			if (!c.moveToFirst()) {
				return;
			}
			long key = System.currentTimeMillis();
			//
			int nameIdx = c.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME);
			int idIdx = c.getColumnIndexOrThrow(MediaStore.Audio.Media._ID);
			//int dataIdx = c.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
			do {
				MusicInfo i = new MusicInfo();
				int id = c.getInt(idIdx);
				i.id = id + "";
				String n = c.getString(nameIdx);
				i.title = n;
				//String p = c.getString(dataIdx);
				//i.path = p;
				//
				key++;
				i.sortkey = key + "";
				list.add(i);
			} while (c.moveToNext());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			c.close();
		}
	}

	private static void loadGenre(Context ctx, ArrayList<ItemInfo> list) {
		final String sel = MediaStore.Audio.Genres.NAME + " != ''";
		final String[] proj = new String[] { MediaStore.Audio.Genres._ID,
				MediaStore.Audio.Genres.NAME };
		Cursor c = MediaUtils.query(ctx,
				MediaStore.Audio.Genres.EXTERNAL_CONTENT_URI, proj, sel, null,
				MediaStore.Audio.Genres.NAME);

		if (DEBUG) {
			Log.d(LOG_TAG, "loadGenre: " + c);
		}
		if (c == null) {
			return;
		}
		list.clear();
		try {
			if (!c.moveToFirst()) {
				return;
			}
			long key = System.currentTimeMillis();

			int idIdx = c.getColumnIndexOrThrow(MediaStore.Audio.Genres._ID);
			int nameIdx = c.getColumnIndexOrThrow(MediaStore.Audio.Genres.NAME);

			do {
				MusicInfo i = new MusicInfo();
				int id = c.getInt(idIdx);
				i.id = id + "";
				String n = c.getString(nameIdx);
				i.title = n;
				//
				key++;
				i.sortkey = key + "";
				list.add(i);
			} while (c.moveToNext());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			c.close();
		}

	}

	private static void loadPlaylist(Context ctx, ArrayList<ItemInfo> list) {
		final String sel = MediaStore.Audio.Playlists.NAME + " != ''";
		final String[] proj = new String[] { MediaStore.Audio.Playlists._ID,
				MediaStore.Audio.Playlists.NAME };
		Cursor c = MediaUtils.query(ctx,
				MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, proj, sel,
				null, MediaStore.Audio.Playlists.NAME);

		if (DEBUG) {
			Log.d(LOG_TAG, "loadPlaylist: " + c);
		}
		if (c == null) {
			return;
		}
		list.clear();
		try {
			if (!c.moveToFirst()) {
				return;
			}
			long key = System.currentTimeMillis();

			int nameIdx = c
					.getColumnIndexOrThrow(MediaStore.Audio.Playlists.NAME);
			int idIdx = c.getColumnIndexOrThrow(MediaStore.Audio.Playlists._ID);
			do {
				MusicInfo i = new MusicInfo();
				int id = c.getInt(idIdx);
				i.id = id + "";
				String n = c.getString(nameIdx);
				i.title = n;
				//
				key++;
				i.sortkey = key + "";
				list.add(i);
			} while (c.moveToNext());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			c.close();
		}
	}

	public MusicFileImpl(URI uri) {
		super(uri);
	}

	public MusicFileImpl(URI uri, ItemInfo info) {
		super(uri, info);
	}

	@Override
	public boolean execute() {
		// TODO
		// try {
		// final MusicInfo item = (MusicInfo) info;
		// if (item == null) {
		// return false;
		// }
		// Context ctx = (Context) fs.getContext();
		// Intent i = new Intent(); // todo
		// String ti = item.title;
		// Intent ci = Intent.createChooser(i, ti);
		// ci.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		// ctx.startActivity(ci);
		// return true;
		// } catch (Exception e) {
		// e.printStackTrace();
		// }
		return false;
	}

	@Override
	public String getContentType() {
		final MusicInfo item = (MusicInfo) info;
		if (item == null) {
			return super.getContentType();
		}
		if (item.type != null) {
			return item.type;
		}
		return super.getContentType();
	}

	@Override
	protected String[] getFolders() {
		return LIST;
	}

	@Override
	public Object getImage() {
		MusicInfo i = (MusicInfo) info;
		if (i != null) {
			Context ctx = (Context) fs.getContext();
			try {
				int id = Integer.parseInt(i.id);
				return ArtworkCache.getCachedArtwork(ctx, id);
			} catch (Exception e) {
			}
		}
		return super.getImage();
	}

	@Override
	protected ItemInfo[] load(Context ctx, int idx) {
		ArrayList<ItemInfo> al = new ArrayList<ItemInfo>();
		switch (idx) {
		case LIST_ALBUM:
			loadAlbum(ctx, al);
			break;
		case LIST_ARTIST:
			loadArtist(ctx, al);
			break;
		case LIST_GENRE:
			loadGenre(ctx, al);
			break;
		case LIST_PLAYLIST:
			loadPlaylist(ctx, al);
			break;
		case LIST_TITLE:
			loadAudio(ctx, al);
			break;
		default:
		}
		return al.toArray(new ItemInfo[0]);
	}

	@Override
	protected IFile newInstance(URI pu, ItemInfo ai) {
		return new MusicFileImpl(pu, ai);
	}

	@Override
	protected ItemInfo[][] lists() {
		return lists;
	}
}
